import java.util.List;
import java.util.ArrayList;

public class GroupObject {
	//Each group is ID'd to be able to quickly pull out the group through the ID
    private List<BlockObject> objects;
    private Point groupCenter; //Average of MaxX, MaxY
    private Point groupEntry; //Where to enter the group
    private Point groupExit; //Where to exit the group
    private boolean accessible; //Can you access this group
    private int groupNumber; //ID Number of Group it is in
    private static int LastUsedGroupNumber;
	public List<BlockObject> getObjects() {
		return objects;
	}
	public void setObjects(List<BlockObject> objects) {
		this.objects = objects;
	}
	public Point getGroupCenter() {
		return groupCenter;
	}
	public void setGroupCenter(Point groupCenter) {
		this.groupCenter = groupCenter;
	}
	public Point getGroupEntry() {
		return groupEntry;
	}
	public void setGroupEntry(Point groupEntry) {
		this.groupEntry = groupEntry;
	}
	public Point getGroupExit() {
		return groupExit;
	}
	public void setGroupExit(Point groupExit) {
		this.groupExit = groupExit;
	}
	public boolean isAccessible() {
		return accessible;
	}
	public void setAccessible(boolean accessible) {
		this.accessible = accessible;
	}
	public int getGroupNumber() {
		return groupNumber;
	}
	public void setGroupNumber(int groupNumber) {
		this.groupNumber = groupNumber;
	}
    
	public static int getLastUsedGroupNumber() {
		return LastUsedGroupNumber;
	}
	public static void setLastUsedGroupNumber(int lastUsedGroupNumber) {
		LastUsedGroupNumber = lastUsedGroupNumber;
	}
	public GroupObject(List<BlockObject> objs)
    {
        objects = objs; //Set Objects
        groupCenter = GetGroupCenter(); //Set Center
    }
    
	public Point GetGroupCenter()
     {
         int SmallestX=-1, SmallestY=-1, BiggestX=-1, BiggestY=-1;
         
         for(BlockObject obj : objects)
         {
             if (obj.getLocation().getX() < SmallestX)
             {
                 SmallestX = obj.getLocation().getX();
             }
             if (obj.getLocation().getX() > BiggestX)
             {
                 BiggestX = obj.getLocation().getX();
             }
             if (obj.getLocation().getY() > BiggestY)
             {
                 BiggestY = obj.getLocation().getY();
             }
             if (obj.getLocation().getY() < SmallestY)
             {
                 SmallestY = obj.getLocation().getY();
             }
         }
         return new Point((SmallestX + BiggestX) / 2, (BiggestY + SmallestY) / 2);
     }
	//Returns Groups of Lambdas
	
	public static List<GroupObject> GroupLambdas(Grid g)
    {
        //List<List<BlockObject>> bos = g.BlockObjects; //Gets all the BlockObjects in a grid
        int startLastUsedGroupNumber=LastUsedGroupNumber;
        List<Point> checkedPoints = new ArrayList<Point>();
        List<GroupObject> Groups = new ArrayList<GroupObject>();

        List<List<BlockObject>> lambdaGroups = new ArrayList<List<BlockObject>>();

        //Search through the grid
        for (int y = 0; y < g.getHeight(); y++)
        {
            for (int x = 0; x < g.getWidth(); x++)
            {
                //Optional check for Contains, Can remove for performance improvement, don't know side effects though
                if (g.getBlockObjects().get(x).get(y).getCharacter() == '\\' && !checkedPoints.contains(new Point(x, y))) 
                {
                    checkedPoints.add(new Point(x, y));
                    Lambda currentLambda = (Lambda)g.getBlockObjects().get(x).get(y);

                    //Check left lambda first
                    int xOffset = -1; 
                    int yOffset = 0;
                    for (int i = 0; i < 2; i++)
                    {
                        if (g.getBlockObjects().get(x + xOffset).get(y + yOffset).getCharacter() == '\\')
                        {
                            Lambda borderLambda = (Lambda)g.getBlockObjects().get(x + xOffset).get(y + yOffset);
                            if (borderLambda.getGroupNumber() != -1)
                            {
                                ((Lambda)g.getBlockObjects().get(x).get(y)).setGroupNumber(borderLambda.getGroupNumber());
                                lambdaGroups.get(borderLambda.getGroupNumber() - startLastUsedGroupNumber - 1).add(g.getBlockObjects().get(x).get(y));
                            }
                        }
                        //Switch to check lambda above
                        yOffset = -1;
                        xOffset = 0;
                    }
                    //If still unset
                    if(currentLambda.getGroupNumber() == -1)
                    {
                        List<BlockObject> tempGroup = new ArrayList<BlockObject>();
                        ((Lambda)g.getBlockObjects().get(x).get(y)).setGroupNumber(++LastUsedGroupNumber);
                        tempGroup.add(g.getBlockObjects().get(x).get(y));
                        lambdaGroups.add(tempGroup);
                    }
                }
            }
        }
        for(List<BlockObject> sheepdaList : lambdaGroups)
        {
            GroupObject tempGO = new GroupObject(sheepdaList);
            tempGO.setGroupNumber(sheepdaList.get(0).getGroupNumber());
            Groups.add(tempGO);            
        }
        return Groups;
    }
	
	public String toString()
    {
        String output = "";
        for(BlockObject bo : objects)
        {
            output += bo.getGroupNumber() + ":" + bo.getCharacter() + " @ " + bo.getLocation().toString() + '\n';
        }
        return output;
    }
}
